/**
 * The proxy server 
 */
package proxy;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetSocketAddress;
import java.util.ArrayList;
import java.util.Collection;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

import org.jboss.netty.bootstrap.ServerBootstrap;
import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;

public class ProxyServer {	

	public enum EServerMode {
		EOpenMode { public String toString() { return "OpenMode"; } },
		EAnonymousMode { public String toString() { return "AnonymousMode"; } },
	}
	
	public static EServerMode serverMode;
	private static Collection<String> blackList;
	private static Collection<String> whiteList;
	
    public static void main(String[] args) {
    	
    	blackList=new ArrayList<String>();
    	whiteList=new ArrayList<String>();
    	
    	blackList.add("www.ynet.co.il");
    	whiteList.add("127.0.0.0");
    	
    	int Port = decideServerMode(args);
    	
        // Configure the server.
		Executor bossExecutor = Executors.newCachedThreadPool();
		Executor workerExecutor = Executors.newCachedThreadPool();
        ServerBootstrap bootstrap = new ServerBootstrap(
                new NioServerSocketChannelFactory(bossExecutor , workerExecutor ));

        // Set up the event pipeline factory.
        bootstrap.setPipelineFactory(new ProxyServerPipelineFactory(serverMode ,bossExecutor , workerExecutor));

        // Bind and start to accept incoming connections.
        bootstrap.bind(new InetSocketAddress(Port));
    }

	/**
	 * Retrieves from the user in which mode should the server run
	 * @param args
	 * @return
	 */
	private static int decideServerMode(String[] args) {
		
		serverMode=EServerMode.EOpenMode;
    	String serverModeStr = "1";
    	int serverModeInt=1;
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		    	
    	int Port=9000;
    	
    	try{
    		Port = Integer.parseInt(args[0]);
    	}
    	catch(NumberFormatException e){
    		System.out.println("Usage : Port can only be an integer, using default: 9000 ");
    	}
    	
    	System.out.println("Which Mode would you like to run the server?\n" +
    						"Open mode: type 1\n" +
    						"Anonymous mode : type 2");
		

		try{
			serverModeStr= br.readLine();
			serverModeInt = Integer.parseInt(serverModeStr);	
		 }
		catch(IOException e){
			System.out.println("Error: wrong mode - using default: Open Mode ");
		}
		catch(NumberFormatException e){
			System.out.println("Error: wrong mode - using default: Open Mode ");
		}
		
		
		switch (serverModeInt){
			case 1:	
				serverMode=EServerMode.EOpenMode;
				System.out.println("Starting server in an Open Mode... ");
	            break;
	            
	    	case 2:	
	    		serverMode=EServerMode.EAnonymousMode;
	    		System.out.println("Starting server in an Anonymous Mode... ");
	            break;
	            
	        default:
	        	System.out.println("Error: wrong mode - using default: Open Mode ");
	        	serverMode=EServerMode.EOpenMode;
				System.out.println("Starting server in an Open Mode... ");
	            break;    	
		}
		return Port;
	}
}
